package com.hhd.flow.controller;

import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.hhd.flow.engine.FlowEngine;
import com.hhd.flow.engine.support.AttachMentType;
import com.hhd.flow.engine.support.DefaultFlowResource;
import com.hhd.flow.engine.support.FlowResource;
import com.hhd.flow.entity.FlowAttachment;
import com.hhd.flow.utils.CommonUtils;
import com.hhd.flow.vo.Result;
import com.hhd.flow.vo.WangEditorVo;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

@RequestMapping("/flow")
@RestController
public class FlowAttachmentController {

    @Autowired
    FlowEngine flowEngine;

    @PostMapping("/upload")
    public Object upload(String attachMentType, MultipartHttpServletRequest request) {
        MultipartFile file = request.getFile("file");
        FlowAttachment attachment = createFlowAttachment(attachMentType, file);
        flowEngine.getFlowAttachmentService().save(attachment);

        return attachment;
    }

    @PostMapping("/uploadForWangEditor")
    public Object uploadForWangEditor(String attachMentType, String baseURL, MultipartHttpServletRequest request) {
        List<FlowAttachment> attachments = createFlowAttachments(attachMentType, request);
        for (FlowAttachment attachment : attachments) {
            attachment.setUrl(baseURL + attachment.getUrl());
            flowEngine.getFlowAttachmentService().save(attachment);
        }
        return new WangEditorVo(attachments);
    }

    @PostMapping("/loadAttachments")
    public Result loadAttachments(@RequestBody LoadAttachmentsVo loadAttachmentsVo) {
        String ids = loadAttachmentsVo.getIds();
        String[] split = ids.split(",");
        return Result.ok(flowEngine.getFlowAttachmentService().lambdaQuery()
                .in(FlowAttachment::getId, split)
                .list());
    }

    @Getter
    @Setter
    private static class LoadAttachmentsVo {
        String ids;
    }

    @GetMapping("/download")
    public void download(String id, HttpServletResponse response) {
        FlowAttachment attachment = flowEngine.getFlowAttachmentService().getById(id);
        if (CommonUtils.isEmpty(attachment)) {
            try {
                response.setStatus(404);
                response.getOutputStream().println("没有找到文件: " + id);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        FlowResource resource = flowEngine.loadResource(attachment);
        try (InputStream inputStream = resource.getInputStream()) {
            response.setContentType("application/x-download");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(resource.getName().getBytes("utf-8"), "iso8859-1"));
            IoUtil.copy(inputStream, response.getOutputStream());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    private List<FlowAttachment> createFlowAttachments(String attachMentType, MultipartHttpServletRequest request) {
        List<FlowAttachment> res = CommonUtils.newList();
        Iterator<String> fileNames = request.getFileNames();
        while (fileNames.hasNext()) {
            res.add(createFlowAttachment(attachMentType, request.getFile(fileNames.next())));
        }
        return res;
    }

    private FlowAttachment createFlowAttachment(String attachMentType, MultipartFile file) {
        FlowAttachment attachment = flowEngine.upload(createResource(file), AttachMentType.forName(attachMentType));
        attachment.setId(IdWorker.getIdStr());
        attachment.setUrl("/flow/download?id=" + attachment.getId());
        return attachment;
    }

    private FlowResource createResource(MultipartFile file) {
        DefaultFlowResource resource = new DefaultFlowResource();
        try {
            resource.setInputStream(file.getInputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        resource.setName(file.getOriginalFilename());
        return resource;
    }
}
